#include "commons.h"
#include "trials.h"
#include "zxLib.h"

float odorLength=1.0;

void setOdorLength(float in){
    odorLength=in;
}

unsigned int getFuncNumber(int targetDigits, char* input) {

    int bitSet[targetDigits];
    int bitValue[targetDigits];
    int n;
    int iter;
    int iter1;

    for (iter = 0; iter < targetDigits; iter++) {
        bitSet[iter] = 0;
        bitValue[iter] = 0;
    }

    home_clr();
    LCDWriteString(input);

    for (iter = 0; iter < targetDigits; iter++) {
        while (!bitSet[iter]) {
            if (S1) {
                bitValue[iter] = 1;
                bitSet[iter] = 1;
            } else if (S2) {
                bitValue[iter] = 2;
                bitSet[iter] = 1;
            } else if (S3) {
                bitValue[iter] = 3;
                bitSet[iter] = 1;
            } else if (S4) {
                bitValue[iter] = 4;
                bitSet[iter] = 1;
            } else if (S5) {
                bitValue[iter] = 5;
                bitSet[iter] = 1;
            }
        }
        home_clr();
        LCDWriteString(input);
        line_2();
        for (iter1 = 0; iter1 < targetDigits; iter1++) {
            lcd_data(bitValue[iter1] + 0x30);
        }
        DelayNmSec(500);
    }
    n = 0;
    for (iter1 = 0; iter1 < targetDigits; iter1++) {
        n = n * 10 + bitValue[iter1];
    }
    return n;
}

void shuffleArray(unsigned int orgArray[], unsigned int arraySize) {
    if (arraySize == 0 || arraySize == 1)
        return;

    int iter;
    for (iter = 0; iter < arraySize; iter++) {
        orgArray[iter] = iter;
    }
    int index, temp;
    for (iter = arraySize - 1; iter > 0; iter--) {
        index = rand() % (iter + 1);
        temp = orgArray[index];
        orgArray[index] = orgArray[iter];
        orgArray[iter] = temp;
    }
}

void LCDWriteString(char* s) {
    int length = strlen(s) > 16 ? 16 : strlen(s);
    int iter;
    for (iter = 0; iter < length; iter++) {
        lcd_data((unsigned) s[iter]);
    }
}

void LCDWriteNumber(int n, int digits, int x, int y) {
    if (digits < 1) {
        return;
    }
    LCD_set_xy(x, y);
    counts_dispose(n);
    if (digits > 2) {
        lcd_data(hunds);
    }
    if (digits > 1) {
        lcd_data(tens);
    }
    lcd_data(ones);
}

void LCDWriteChar(char ch, int x, int y) {
    LCD_set_xy(x, y);
    lcd_data(ch);
}


void test_odor_Advanced(int totalTrial) {
    home_clr();
    int i = 0;

    while (i < totalTrial) {
        counts_dispose(i);
        LCD_set_xy(1, 1);
        lcd_data(hunds);
        lcd_data(tens);
        lcd_data(ones);
        lcd_data(',');
        LCD_set_xy(6, 1);
        lcd_data(0x31);
        Valve_ON(odor_A, period * 2);
        Out1 = 1;
        DelayNmSecNew(1000);
        Valve_OFF(odor_A);
        Out1 = 0;
        DelayNmSecNew(3000);
        LCD_set_xy(6, 1);
        lcd_data(0x32);
        Valve_ON(odor_B, period * 2);
        Out2 = 1;
        DelayNmSecNew(1000);
        Valve_OFF(odor_B);
        Out2 = 0;
        DelayNmSecNew(3000);
        LCD_set_xy(6, 1);
        lcd_data(0x33);
        Valve_ON(4, period * 2);
        Out3 = 1;
        DelayNmSecNew(1000);
        Valve_OFF(4);
        Out3 = 0;
        DelayNmSecNew(3000);
        LCD_set_xy(6, 1);
        lcd_data(0x34);
        Valve_ON(5, period * 2);
        Out4 = 1;
        DelayNmSecNew(1000);
        Valve_OFF(5);
        Out4 = 0;
        DelayNmSecNew(3000);
        i++;
    }

}

void zxDNMSSessions(int interOdorDelay, int interti, int trialNumperSess, float waterlen, float delayBeforeReward, int missLimit, int totalSession) {
    localSendOnce(SpS3S2, 1);
    localSendOnce(SpStepN, 3);

    DelayNmSecNew(500);

    int currentTrial = 0;
    int currentSession = 0;


    while ((currentMiss < missLimit) && (currentSession < totalSession)) {
        currentSession++;
        localSendOnce(SpStepN, 3);
        localSendOnce(SpSessN, currentSession);
        localSendOnce(SptrialNperSess, trialNumperSess);
        localSendOnce(SpOdorDelay, interOdorDelay);
        localSendOnce(SpSess, 1);

        home_clr();
        puts_lcd((unsigned char*) &text7[0], sizeof (text7));
        line_2();
        puts_lcd((unsigned char*) &text8[0], sizeof (text8));
        LCDWriteNumber(currentSession, 2, 2, 2);

        timerCounterI = 0;
        while (timerCounterI < 3000) // inter session delay
        {
        }
        currentTrial = 0;
        hit = 0;
        miss = 0;
        falseAlarm = 0;
        correctRejection = 0;
        unsigned int shuffledList[4];
        while (currentTrial < (trialNumperSess) && currentMiss < missLimit) {
            shuffleArray(shuffledList, 4);
            int iter;
            for (iter = 0; iter < 4 && currentMiss < missLimit; iter++) {
                int firstOdor, secondOdor;
                int index = shuffledList[iter];
                firstOdor = (index == 0 || index == 2) ? odor_A : odor_B;
                secondOdor = (index == 1 || index == 2) ? odor_A : odor_B;
                LCD_set_xy(1, 1);
                lcd_data(firstOdor + 0x3F);
                lcd_data(secondOdor + 0x3F);
                zxDNMS(firstOdor, odorLength, interOdorDelay, secondOdor, waterlen, interti, delayBeforeReward);
                currentTrial++;
            }
        }

        localSendOnce(SpSessHit, hit);
        localSendOnce(SpSessMiss, miss);
        localSendOnce(SpSessFA, falseAlarm);
        localSendOnce(SpSessCR, correctRejection);
        localSendOnce(SpSessCorrRate, correctRatio);
        localSendOnce(SpSess, 0);
    }
    localSendOnce(SpTrain, 0); // send it's the end

}

void zxDNMSLaserSessions(int thisdelay, int interti, int trialsPerSession, float WaterLen, int missLimit, int totalSession, float delay_before_reward, int delay1, int delay2) {
    localSendOnce(SpStepN, 0);
    DelayNmSecNew(2 * 1000);

    int currentTrial = 0;
    int currentSession = 0;

    while ((currentMiss < missLimit) && (currentSession < totalSession)) {
        currentSession++;
        localSendOnce(SpOdorDelay, thisdelay);
        localSendOnce(SpSess, 1);

        home_clr();
        puts_lcd((unsigned char*) &text7[0], sizeof (text7));
        line_2();
        puts_lcd((unsigned char*) &text8[0], sizeof (text8));

        LCDWriteNumber(currentSession, 2, 2, 2);
        currentTrial = 0;
        hit = 0;
        miss = 0;
        falseAlarm = 0;
        correctRejection = 0;
        unsigned int shuffledList[4];
        while (currentTrial < trialsPerSession && currentMiss < missLimit) {
            shuffleArray(shuffledList, 4);
            int iter;
            for (iter = 0; iter < 4 && currentMiss < missLimit; iter++) {
                DelayNmSec(1000);
                int firstOdor, secondOdor;
                int index = shuffledList[iter];
                firstOdor = (index == 0 || index == 2) ? odor_A : odor_B;
                secondOdor = (index == 1 || index == 2) ? odor_A : odor_B;
                LCD_set_xy(1, 1);
                lcd_data(firstOdor + 0x3F);
                lcd_data(secondOdor + 0x3F);
                zxDNMSLaser(firstOdor, odorLength, thisdelay, secondOdor, 1, WaterLen, interti, 0, delay_before_reward, delay1, delay2, currentTrial);
                currentTrial++;
            }
        }
        localSendOnce(SpSess, 0);
    }
    localSendOnce(SpTrain, 0); // send it's the end
}

void zxDNMS(int FirstOdorIn, float odorLength, int OdorDelayIn, int SecondOdorIn, float WaterLIn, int IntervalIn, float delay_before_reward) {
    localSendOnce(FirstOdorIn + 7, 1); // odor_A=2, spOdor_A=9
    LCDWriteChar('1', 4, 1);
    Valve_ON(FirstOdorIn, period * 2);
    timerCounterI = 0;
    while (timerCounterI < odorLength * 1000) {
        if (LickOnPin) {
            localSendOnce(SpLick, 1);
            DelayNmSecNew(20);
        }
    }
    Valve_OFF(FirstOdorIn);
    localSendOnce(FirstOdorIn + 7, 0); // 0 for close
    LCDWriteChar('d', 4, 1);
    timerCounterI = 0;
    while (timerCounterI < OdorDelayIn * 1000) {
        if (LickOnPin) {
            localSendOnce(SpLick, 1);
            DelayNmSecNew(20);
        }
    }
    LCDWriteChar('2', 4, 1);
    localSendOnce(SecondOdorIn + 7, 1); // 1 for open
    Valve_ON(SecondOdorIn, period * 2);
    timerCounterI = 0;
    while (timerCounterI < odorLength * 1000) {
        if (LickOnPin) {
            localSendOnce(SpLick, 1);
            DelayNmSecNew(20);

        }
    }
    Valve_OFF(SecondOdorIn);
    localSendOnce(SecondOdorIn + 7, 0); // 0 for close
    LCDWriteChar('D', 4, 1);
    timerCounterI = 0;
    while (timerCounterI < delay_before_reward * 1000) // the delay after second odor
    {
        if (LickOnPin) {
            localSendOnce(SpLick, 1);
            DelayNmSecNew(20);
        }
    }

    LCDWriteChar('R', 4, 1);
    Flags.lick = 0;
    timerCounterI = 0;
    while (timerCounterI < WaterLIn * 1000) {
        if (LickOnPin) {
            Flags.lick = 1;
            localSendOnce(SpLick, 1);
            if (FirstOdorIn != SecondOdorIn) {
                Valve_ON(water_sweet, period * 2);
                localSendOnce(SpWater_sweet, 1);
            }
            DelayNmSecNew(20);
        }
    }
    Valve_OFF(water_sweet);

    if (Flags.lick) {
        Flags.lick = 0;
        if (FirstOdorIn != SecondOdorIn) {
            localSendOnce(SpWater_sweet, 0);
            hit++;
            localSendOnce(SpHit, 1);
            LCDWriteNumber((int) hit, 3, 6, 1);
        } else {
            falseAlarm++;
            localSendOnce(SpFalseAlarm, 1);
            LCDWriteNumber((int) falseAlarm, 3, 6, 2);
        }
    } else {
        if (FirstOdorIn != SecondOdorIn) {
            miss++;
            localSendOnce(SpMiss, 1);
            LCDWriteNumber((int) miss, 3, 10, 1);
        } else {
            correctRejection++;
            localSendOnce(SpCorrectRejection, 1);
            LCDWriteNumber((int) correctRejection, 3, 10, 2);
        }
    }
    int totalTrials = hit + correctRejection + miss + falseAlarm;
    LCDWriteNumber(totalTrials, 3, 14, 2);
    if (hit + correctRejection > 0) {
        correctRatio = 100 * (hit + correctRejection) / totalTrials;
        LCDWriteNumber(correctRatio, 2, 14, 1);
    }

    LCDWriteChar('I', 4, 1);
    localSendOnce(SpITI, 1);
    timerCounterI = 0;
    while (timerCounterI < IntervalIn * 1000) {
        if (LickOnPin) {
            localSendOnce(SpLick, 1);
            DelayNmSecNew(20);
        }
    }
    localSendOnce(SpITI, 0);
}

void zxDNMSLaser(int FirstOdorIn, float FirOdorLen, int OdorDelayIn, int SecondOdorIn, int SecOdorLen, float WaterLIn, int IntervalIn, int prolong, float delay_before_reward, int delay1, int delay2, int temptrial) {
    localSendOnce(Splaser, (temptrial % 2 == 0) ? 0 : 1);
    Valve_ON(FirstOdorIn, period * 2);
    //
    //    if (FirstOdorIn == odor_A) Out1 = 1;
    //    else if (FirstOdorIn == odor_B) Out2 = 1;

    localSendOnce(FirstOdorIn + 7, 1);

    timerCounterI = 0;
    while (timerCounterI < (FirOdorLen)*1000) {
        if (LickOnPin) localSendOnce(SpLick, 1);
    }

    Valve_OFF(FirstOdorIn);
    //
    //    if (FirstOdorIn == odor_A) Out1 = 0;
    //    else if (FirstOdorIn == odor_B) Out2 = 0;

    localSendOnce(FirstOdorIn + 7, 0);

    ///////////-inter odor interval-/////////////////
    if (temptrial % 2 == 0) {
        timerCounterI = 0;
        while (timerCounterI < OdorDelayIn * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
    } else {
        LCD_set_xy(3, 1);
        lcd_data('L');
        timerCounterI = 0;
        while (timerCounterI < delay1 * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }

        zxLaser(laserFreq, durationPerLaserStim, delay2 * 1000);

        timerCounterI = 0;
        while (timerCounterI < (OdorDelayIn - delay1 - delay2)*1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
        LCD_set_xy(3, 1);
        lcd_data('.');
    }

    ///////////-Second odor-/////////////////

    Valve_ON(SecondOdorIn, period * 2);
    //    if (SecondOdorIn == odor_A) Out1 = 1;
    //    else if (SecondOdorIn == odor_B) Out2 = 1;

    localSendOnce(SecondOdorIn + 7, 1);
    timerCounterI = 0;
    while (timerCounterI < (FirOdorLen)*1000) {
        if (LickOnPin) localSendOnce(SpLick, 1);
    }
    Valve_OFF(SecondOdorIn);

    //    if (SecondOdorIn == odor_A) Out1 = 0;
    //    else if (SecondOdorIn == odor_B) Out2 = 0;

    localSendOnce(SecondOdorIn + 7, 0);
    ////////-delay before reward-///////

    timerCounterI = 0;
    while (timerCounterI < delay_before_reward * 1000) // the delay after second odor
    {
        if (LickOnPin) localSendOnce(SpLick, 1);
    }

    if (FirstOdorIn != SecondOdorIn) {
        ///////////-reward-/////////////////
        Flags.lick = 0;

        timerCounterI = 0;
        while (timerCounterI < WaterLIn * 1000) {
            if (LickOnPin) {
                localSendOnce(SpLick, 1);
                Valve_ON(water_sweet, period * 2);
                localSendOnce(SpWater_sweet, 1);
                Flags.lick = 1;
            }
        }
        Valve_OFF(water_sweet);
        localSendOnce(SpWater_sweet, 0);

        if (Flags.lick) {
            Flags.lick = 0;
            currentMiss = 0;
            hit++;
            localSendOnce(SpHit, 1);
            LCDWriteNumber(hit, 3, 6, 1);
        } else {
            currentMiss++;
            miss++;
            localSendOnce(SpMiss, 1);
            LCDWriteNumber(miss, 3, 10, 1);
        }
    } else {
        ///////////- punishment-/////////////////
        Flags.lick = 0;
        timerCounterI = 0;
        while (timerCounterI < WaterLIn * 1000) {
            if (LickOnPin) {
                localSendOnce(SpLick, 1);
                Flags.lick = 1;
            }
        }
        if (Flags.lick) {
            timerCounterI = 0;
            while (timerCounterI < prolong * 1000) { // longer ITI

            }
            Flags.lick = 0; // Reset flag
            falseAlarm++;
            currentMiss = 0;
            localSendOnce(SpFalseAlarm, 1);
            LCDWriteNumber(falseAlarm, 3, 6, 2);
        } else {
            correctRejection++;
            Flags.lick = 0;
            localSendOnce(SpCorrectRejection, 1);
            LCDWriteNumber(correctRejection, 3, 10, 2);
        }
    }
    // Total Trials
    int totalTrials = hit + correctRejection + miss + falseAlarm;
    LCDWriteNumber(totalTrials, 3, 14, 2);
    // Discrimination rate
    if (hit + correctRejection > 0) {
        correctRatio = 100 * (hit + correctRejection) / totalTrials;
        LCDWriteNumber(correctRatio, 2, 14, 1);
    }

    ///--ITI1---///
    timerCounterI = 0;
    while (timerCounterI < IntervalIn * 1000) {
        if (LickOnPin) localSendOnce(SpLick, 1);
    }
}

void zxLaser(int FreqStim, int DuraStim, int totalStimTime) {
    //                        LCD_set_xy(1,1);
    //                    lcd_data(0x33);
    //                    lcd_data(0x30);
    //float Interval;
    int Interval = (1000 / FreqStim) - DuraStim;
    int ind;
    int NumSpikeBurst = (totalStimTime / 1000) * FreqStim;

    for (ind = 1; ind <= NumSpikeBurst; ind++) {

        Out3 = 1;

        // delay for DuraStim
        timerCounterI = 0;
        while (timerCounterI < DuraStim) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }

        Out3 = 0;

        // delay for Interval
        timerCounterI = 0;
        while (timerCounterI < Interval) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
    }
}

void zxGo_nogo_autoSwitch(int odorType, int trialInSesion, int go_odor, int nogo_odor, int odorlen, int delay, float waterlen,                                                                  \
             int ITI, int odorlaseryes, int delaylaseryes, int waterlaseryes, int ITI1, int ITI2) {
    if (odorType >= 3) {
        odorType = (rand() % 2) + 1;
    }
    if (odorType == 2) {
        int temp;
        temp = nogo_odor;
        nogo_odor = go_odor;
        go_odor = temp;
    }
    localSendOnce(SpStepN, 0);
    DelayNmSecNew(2 * 1000);

    int currentTrial = 0;
    int trial = 0;
    int sessionNum = 0;
    int lastRatio = 0;
    while (1) { //while (1)  no stop
        if ((correctRatio >= HighThres) || (correctRatio >= lowThres && lastRatio >= lowThres)) {
            int temp = nogo_odor;
            nogo_odor = go_odor;
            go_odor = temp;
        }
        lastRatio = correctRatio;
        sessionNum++;
        localSendOnce(SpSess, 1);
        home_clr();
        puts_lcd((unsigned char*) &text7[0], sizeof (text7));
        line_2();
        puts_lcd((unsigned char*) &text8[0], sizeof (text8));

        LCD_set_xy(1, 1);
        if (go_odor == odor_A) {
            LCDWriteString("Ago");
        } else {
            LCDWriteString("Bgo");
        }

        counts_dispose(sessionNum);
        LCD_set_xy(2, 2);
        lcd_data(tens);
        lcd_data(ones);

        currentTrial = 0;
        hit = 0;
        miss = 0;
        falseAlarm = 0;
        correctRejection = 0;

        while (currentTrial < trialInSesion) {
            trial = 0;
            Flags.ab = 0;
            Flags.ba = 0;

            while (trial < 2) {
                int ValRan = rand() % 2; //0-1???
                switch (ValRan) {
                    case 0:
                        if (Flags.ab) {
                            break;
                        } else {
                            zxGo(go_odor, nogo_odor, odorlen, delay, waterlen, ITI, odorlaseryes, delaylaseryes, waterlaseryes, ITI1, ITI2);
                            Flags.ab = 1;
                            trial++;
                            currentTrial++;
                            break;
                        }

                    case 1:
                        if (Flags.ba) {
                            break;
                        } else {
                            zxNogo(go_odor, nogo_odor, odorlen, delay, waterlen, ITI, odorlaseryes, delaylaseryes, waterlaseryes, ITI1, ITI2);
                            Flags.ba = 1;
                            trial++;
                            currentTrial++;
                            break;
                        }
                }
            }
        }
        localSendOnce(SpSess, 0);
    }
    localSendOnce(SpTrain, 0); // send it's the end
}

void zxGo(int go_odor, int nogo_odor, int odorlen, int delay, float waterlen,                                                                  \
             int ITI, int odorlaseryes, int delaylaseryes, int waterlaseryes, int ITI1, int ITI2) {
    Valve_ON(go_odor, period * 2);

    if (go_odor == odor_A) localSendOnce(SpOdor_A, 1);
    else if (go_odor == odor_B) localSendOnce(SpOdor_B, 1);

    if (odorlaseryes == 1) {
        Out3 = 1;
        timerCounterI = 0;
        while (timerCounterI < odorlen * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
        Out3 = 0;
    } else {
        timerCounterI = 0;
        while (timerCounterI < odorlen * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
    }

    Valve_OFF(go_odor);
    //---delay--//
    if (delaylaseryes == 1) {
        Out3 = 1;
        timerCounterI = 0;
        while (timerCounterI < delay * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
        Out3 = 0;
    } else {
        timerCounterI = 0;
        while (timerCounterI < delay * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
    }

    //---water--//
    Flags.lick = 0;

    if (waterlaseryes == 1) {
        Out3 = 1;
        timerCounterI = 0;
        while (timerCounterI < waterlen * 1000) {
            if (LickOnPin) {
                localSendOnce(SpLick, 1);
                Valve_ON(water_sweet, period * 2);
                localSendOnce(SpWater_sweet, 1);
                Flags.lick = 1;
            }
        }
        //Out3=0;
    } else {
        timerCounterI = 0;
        while (timerCounterI < waterlen * 1000) {
            if (LickOnPin) {
                localSendOnce(SpLick, 1);
                Valve_ON(water_sweet, period * 2);
                localSendOnce(SpWater_sweet, 1);
                Flags.lick = 1;
            }
        }
    }
    Valve_OFF(water_sweet);
    if (Flags.lick) {
        Flags.lick = 0;
        currentMiss = 0;
        hit++;
        localSendOnce(SpHit, 1);
        counts_dispose(hit);
        LCD_set_xy(6, 1);
        lcd_data(hunds);
        lcd_data(tens);
        lcd_data(ones);
    } else {
        currentMiss++;
        miss++;
        localSendOnce(SpMiss, 1);
        counts_dispose(miss);
        LCD_set_xy(10, 1);
        lcd_data(hunds);
        lcd_data(tens);
        lcd_data(ones);

    }
    // Total Trials
    int totalTrials = hit + correctRejection + miss + falseAlarm;
    counts_dispose(totalTrials);
    LCD_set_xy(14, 2);
    lcd_data(hunds);
    lcd_data(tens);
    lcd_data(ones);

    // Discrimination rate
    if (hit + correctRejection > 0) {
        correctRatio = 100 * (hit + correctRejection) / totalTrials;
        counts_dispose(correctRatio);
        LCD_set_xy(14, 1);
        lcd_data(tens);
        lcd_data(ones);
    }
    //--iti--//
    timerCounterI = 0;
    while (timerCounterI < ITI1 * 1000) {
        if (LickOnPin) localSendOnce(SpLick, 1);
    }

    if (ITI2 != 0) {
        Out3 = 1;
        timerCounterI = 0;
        while (timerCounterI < ITI2 * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
    }
    Out3 = 0;
    timerCounterI = 0;
    while (timerCounterI < (ITI - ITI1 - ITI2) * 1000) {
        if (LickOnPin) localSendOnce(SpLick, 1);
    }
}

void zxNogo(int go_odor, int nogo_odor, int odorlen, int delay, float waterlen,                                                                  \
          int ITI, int odorlaseryes, int delaylaseryes, int waterlaseryes, int ITI1, int ITI2) {
    Valve_ON(nogo_odor, period * 2);

    if (nogo_odor == odor_A) localSendOnce(SpOdor_A, 1);
    else if (nogo_odor == odor_B) localSendOnce(SpOdor_B, 1);

    if (odorlaseryes == 1) {
        Out3 = 1;
        timerCounterI = 0;
        while (timerCounterI < odorlen * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
        Out3 = 0;
    } else {
        timerCounterI = 0;
        while (timerCounterI < odorlen * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
    }

    Valve_OFF(nogo_odor);

    //---delay--//

    if (delaylaseryes == 1) {
        Out3 = 1;
        timerCounterI = 0;
        while (timerCounterI < delay * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
        Out3 = 0;
    } else {
        timerCounterI = 0;
        while (timerCounterI < delay * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
    }


    //---water--//
    Flags.lick = 0;

    if (waterlaseryes == 1) {
        Out3 = 1;
        timerCounterI = 0;
        while (timerCounterI < waterlen * 1000) {
            if (LickOnPin) {
                localSendOnce(SpLick, 1);

                localSendOnce(SpWater_sweet, 1);
                Flags.lick = 1;
            }
        }
        //Out3=0;
    } else {
        timerCounterI = 0;
        while (timerCounterI < waterlen * 1000) {
            if (LickOnPin) {
                localSendOnce(SpLick, 1);

                localSendOnce(SpWater_sweet, 1);
                Flags.lick = 1;
            }
        }
    }


    if (Flags.lick) {
        timerCounterI = 0;
        while (timerCounterI < 0 * 1000) // longer ITI
        {
        }

        Flags.lick = 0; // Reset flag

        falseAlarm++;
        currentMiss = 0;
        localSendOnce(SpFalseAlarm, 1);
        counts_dispose(falseAlarm);
        LCD_set_xy(6, 2);
        lcd_data(hunds);
        lcd_data(tens);
        lcd_data(ones);


    } else {
        correctRejection++;
        Flags.lick = 0;
        localSendOnce(SpCorrectRejection, 1);
        counts_dispose(correctRejection);
        LCD_set_xy(10, 2);
        lcd_data(hunds);
        lcd_data(tens);
        lcd_data(ones);
    }

    // Total Trials
    int totalTrials = hit + correctRejection + miss + falseAlarm;
    counts_dispose(totalTrials);
    LCD_set_xy(14, 2);
    lcd_data(hunds);
    lcd_data(tens);
    lcd_data(ones);

    // Discrimination rate
    if (hit + correctRejection > 0) {
        correctRatio = 100 * (hit + correctRejection) / (hit + miss + correctRejection + falseAlarm);
        counts_dispose(correctRatio);
        LCD_set_xy(14, 1);
        lcd_data(tens);
        lcd_data(ones);
    }

    //--iti--//
    timerCounterI = 0;
    while (timerCounterI < ITI1 * 1000) {
        if (LickOnPin) localSendOnce(SpLick, 1);
    }

    if (ITI2 != 0) {
        Out3 = 1;
        timerCounterI = 0;
        while (timerCounterI < ITI2 * 1000) {
            if (LickOnPin) localSendOnce(SpLick, 1);
        }
    }
    Out3 = 0;
    timerCounterI = 0;
    while (timerCounterI < (ITI - ITI1 - ITI2) * 1000) {
        if (LickOnPin) localSendOnce(SpLick, 1);
    }
}


